home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / progjrn / pj_7_5.arc / TEST360.C < prev    next >
Text File  |  1989-06-11  |  7KB  |  207 lines

  1. /*
  2.  * *** Listing 2 ***
  3.  *
  4.  * Sample program to illustrate VGA line drawing in 360x480
  5.  * 256-color mode.
  6.  *
  7.  * Compiled with Turbo C 2.0.
  8.  *
  9.  * Must be linked with Listing 1 with a command line like:
  10.  *
  11.  *    tcc l2 l1.asm
  12.  *
  13.  * By Michael Abrash.  6/2/89.
  14.  */
  15. #include <dos.h>                 /* contains geninterrupt */
  16.  
  17. #define TEXT_MODE       0x03
  18. #define BIOS_VIDEO_INT  0x10
  19. #define X_MAX           360      /* working screen width */
  20. #define Y_MAX           480      /* working screen height */
  21.  
  22. extern void Draw360x480Dot();
  23. extern void Set360x480Mode();
  24.  
  25. /*
  26.  * Draws a line in octant 0 or 3 ( |DeltaX| >= DeltaY ).
  27.  * |DeltaX|+1 points are drawn.
  28.  */
  29. void Octant0(X0, Y0, DeltaX, DeltaY, XDirection, Color)
  30. unsigned int X0, Y0;          /* coordinates of start of the line */
  31. unsigned int DeltaX, DeltaY;  /* length of the line */
  32. int XDirection;               /* 1 if line is drawn left to right,
  33.                                  -1 if drawn right to left */
  34. int Color;                    /* color in which to draw line */
  35. {
  36.    int DeltaYx2;
  37.    int DeltaYx2MinusDeltaXx2;
  38.    int ErrorTerm;
  39.  
  40.    /* Set up initial error term and values used inside drawing loop */
  41.    DeltaYx2 = DeltaY * 2;
  42.    DeltaYx2MinusDeltaXx2 = DeltaYx2 - (int) ( DeltaX * 2 );
  43.    ErrorTerm = DeltaYx2 - (int) DeltaX;
  44.  
  45.    /* Draw the line */
  46.    Draw360x480Dot(X0, Y0, Color);   /* draw the first pixel */
  47.    Read360x480Dot(X0, Y0);   /* draw the first pixel */
  48.    while ( DeltaX-- ) {
  49.       /* See if it's time to advance the Y coordinate */
  50.       if ( ErrorTerm >= 0 ) {
  51.          /* Advance the Y coordinate & adjust the error term
  52.             back down */
  53.          Y0++;
  54.          ErrorTerm += DeltaYx2MinusDeltaXx2;
  55.       } else {
  56.          /* Add to the error term */
  57.          ErrorTerm += DeltaYx2;
  58.       }
  59.       X0 += XDirection;          /* advance the X coordinate */
  60.       Draw360x480Dot(X0, Y0, Color);    /* draw a pixel */
  61.    }
  62. }
  63.  
  64. /*
  65.  * Draws a line in octant 1 or 2 ( |DeltaX| < DeltaY ).
  66.  * |DeltaY|+1 points are drawn.
  67.  */
  68. void Octant1(X0, Y0, DeltaX, DeltaY, XDirection, Color)
  69. unsigned int X0, Y0;          /* coordinates of start of the line */
  70. unsigned int DeltaX, DeltaY;  /* length of the line */
  71. int XDirection;               /* 1 if line is drawn left to right,
  72.                                  -1 if drawn right to left */
  73. int Color;                    /* color in which to draw line */
  74. {
  75.    int DeltaXx2;
  76.    int DeltaXx2MinusDeltaYx2;
  77.    int ErrorTerm;
  78.  
  79.    /* Set up initial error term and values used inside drawing loop */
  80.    DeltaXx2 = DeltaX * 2;
  81.    DeltaXx2MinusDeltaYx2 = DeltaXx2 - (int) ( DeltaY * 2 );
  82.    ErrorTerm = DeltaXx2 - (int) DeltaY;
  83.  
  84.    Draw360x480Dot(X0, Y0, Color);    /* draw the first pixel */
  85.    Read360x480Dot(X0, Y0);   /* draw the first pixel */
  86.    while ( DeltaY-- ) {
  87.       /* See if it's time to advance the X coordinate */
  88.       if ( ErrorTerm >= 0 ) {
  89.          /* Advance the X coordinate & adjust the error term
  90.             back down */
  91.          X0 += XDirection;
  92.          ErrorTerm += DeltaXx2MinusDeltaYx2;
  93.       } else {
  94.          /* Add to the error term */
  95.          ErrorTerm += DeltaXx2;
  96.       }
  97.       Y0++;                   /* advance the Y coordinate */
  98.       Draw360x480Dot(X0, Y0,Color);  /* draw a pixel */
  99.    }
  100. }
  101.  
  102. /*
  103.  * Draws a line on the EGA or VGA.
  104.  */
  105. void EVGALine(X0, Y0, X1, Y1, Color)
  106. int X0, Y0;    /* coordinates of one end of the line */
  107. int X1, Y1;    /* coordinates of the other end of the line */
  108. unsigned char Color;    /* color in which to draw line */
  109. {
  110.    int DeltaX, DeltaY;
  111.    int Temp;
  112.  
  113.    /* Save half the line-drawing cases by swapping Y0 with Y1
  114.       and X0 with X1 if Y0 is greater than Y1. As a result, DeltaY
  115.       is always > 0, and only the octant 0-3 cases need to be
  116.       handled. */
  117.    if ( Y0 > Y1 ) {
  118.       Temp = Y0;
  119.       Y0 = Y1;
  120.       Y1 = Temp;
  121.       Temp = X0;
  122.       X0 = X1;
  123.       X1 = Temp;
  124.    }
  125.  
  126.    /* Handle as four separate cases, for the four octants in which
  127.       Y1 is greater than Y0 */
  128.    DeltaX = X1 - X0;    /* calculate the length of the line
  129.                            in each coordinate */
  130.    DeltaY = Y1 - Y0;
  131.    if ( DeltaX > 0 ) {
  132.       if ( DeltaX > DeltaY ) {
  133.          Octant0(X0, Y0, DeltaX, DeltaY, 1, Color);
  134.       } else {
  135.          Octant1(X0, Y0, DeltaX, DeltaY, 1, Color);
  136.       }
  137.    } else {
  138.       DeltaX = -DeltaX;             /* absolute value of DeltaX */
  139.       if ( DeltaX > DeltaY ) {
  140.          Octant0(X0, Y0, DeltaX, DeltaY, -1, Color);
  141.       } else {
  142.          Octant1(X0, Y0, DeltaX, DeltaY, -1, Color);
  143.       }
  144.    }
  145. }
  146.  
  147. /*
  148.  * Subroutine to draw a rectangle full of vectors, of the
  149.  * specified length and in varying colors, around the
  150.  * specified rectangle center.
  151.  */
  152. void VectorsUp(XCenter, YCenter, XLength, YLength)
  153. int XCenter, YCenter;   /* center of rectangle to fill */
  154. int XLength, YLength;   /* distance from center to edge
  155.                            of rectangle */
  156. {
  157.    int WorkingX, WorkingY, Color = 1;
  158.  
  159.    /* Lines from center to top of rectangle */
  160.    WorkingX = XCenter - XLength;
  161.    WorkingY = YCenter - YLength;
  162.    for ( ; WorkingX < ( XCenter + XLength ); WorkingX++ )
  163.       EVGALine(XCenter, YCenter, WorkingX, WorkingY, Color++);
  164.  
  165.    /* Lines from center to right of rectangle */
  166.    WorkingX = XCenter + XLength - 1;
  167.    WorkingY = YCenter - YLength;
  168.    for ( ; WorkingY < ( YCenter + YLength ); WorkingY++ )
  169.       EVGALine(XCenter, YCenter, WorkingX, WorkingY, Color++);
  170.  
  171.    /* Lines from center to bottom of rectangle */
  172.    WorkingX = XCenter + XLength - 1;
  173.    WorkingY = YCenter + YLength - 1;
  174.    for ( ; WorkingX >= ( XCenter - XLength ); WorkingX-- )
  175.       EVGALine(XCenter, YCenter, WorkingX, WorkingY, Color++);
  176.  
  177.    /* Lines from center to left of rectangle */
  178.    WorkingX = XCenter - XLength;
  179.    WorkingY = YCenter + YLength - 1;
  180.    for ( ; WorkingY >= ( YCenter - YLength ); WorkingY-- )
  181.       EVGALine(XCenter, YCenter, WorkingX, WorkingY, Color++);
  182. }
  183.  
  184. /*
  185.  * Sample program to draw four rectangles full of lines.
  186.  */
  187. int main()
  188. {
  189.    char temp;
  190.  
  191.    Set360x480Mode();
  192.  
  193.    /* Draw each of four rectangles full of vectors */
  194.    VectorsUp(X_MAX / 4, Y_MAX / 4, X_MAX / 4, Y_MAX / 4, 1);
  195.    VectorsUp(X_MAX * 3 / 4, Y_MAX / 4, X_MAX / 4, Y_MAX / 4, 2);
  196.    VectorsUp(X_MAX / 4, Y_MAX * 3 / 4, X_MAX / 4, Y_MAX / 4, 3);
  197.    VectorsUp(X_MAX * 3 / 4, Y_MAX * 3 / 4, X_MAX / 4, Y_MAX / 4, 4);
  198.  
  199.    /* Wait for the enter key to be pressed */
  200.    scanf("%c", &temp);
  201.  
  202.    /* Back to text mode */
  203.    _AX = TEXT_MODE;
  204.    geninterrupt(BIOS_VIDEO_INT);
  205. }
  206.  
  207.